package uf.audit.util;

import com.alibaba.fastjson.JSON;
import com.jfinal.core.Controller;
import org.apache.log4j.Logger;

import java.io.File;
import java.io.InputStream;
import java.security.DigestException;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 全局工具单元类
 * 
 * @author sunny
 *
 */
public class Utils {

	private static final String SYSINFO_PROPERTIES = "/sysinfo.properties";
	public static String ROOT;
	private static Map<String, Properties> propCachs = new HashMap<String, Properties>();

	private static Logger log;

	private static Logger getLogger() {
		if (log == null)
			log = Logger.getLogger(Utils.class);
		return log;
	}

	/**
	 * 采用cache，避免每次访问都要读取文件
	 * 
	 * @param cfgPath
	 * @return
	 * @throws Exception
	 */
	public static Properties getProperties(String cfgPath) throws Exception {
		Properties properties = propCachs.get(cfgPath);
		if (properties == null) {
			properties = new Properties();
			InputStream stream = Utils.class.getResourceAsStream(cfgPath);
			try {
				properties.load(stream);
				stream.close();
				propCachs.put(cfgPath, properties);
			} catch (Exception e) {
				getLogger().error(e.getMessage(), e);
				throw e;
			}
		}
		return properties;
	}

	public static boolean isLogin(Controller controller) {
		return getLogin(controller) != null;
	}

	public static void cleanLogin(Controller controller) {
		controller.getSession(true).removeAttribute(Consts.SESSION_USER_ID);
		controller.removeSessionAttr("questions");
	}

	public static void setLogin(Controller controller, String userId) {
		controller.getSession(true).setAttribute(Consts.SESSION_USER_ID, userId);
	}

	public static String getLogin(Controller controller) {
		return (String) controller.getSession(true).getAttribute(Consts.SESSION_USER_ID);
	}

	@SuppressWarnings("unchecked")
	public static Map<String, Object> parseJson(String jsonText) {
		return (Map<String, Object>) JSON.parse(jsonText);
	}

	public static String getDateTime() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		return sdf.format(new Date());
	}

	public static int getRandNum(int range, Set<Integer> exts) {
		Random random = new Random();
		int s = random.nextInt(range);
		if (exts.contains(s)) {
			return getRandNum(range, exts);
		} else {
			exts.add(s);
			return s;
		}
	}

	private static Map<String, String> attachWithType = new HashMap<String, String>();

	public static String getAttachmentDir(String type) {
		String result = attachWithType.get(type);
		if (result == null) {
			String dir = ROOT + "/" + com.jfinal.core.Const.DEFAULT_BASE_DOWNLOAD_PATH;
			Properties sysInfo = null;
			try {
				sysInfo = getProperties(SYSINFO_PROPERTIES);
			} catch (Exception e) {
				e.printStackTrace();
			}
			if (sysInfo != null && (sysInfo.get("attach") != null)) {
				dir = sysInfo.getProperty("attach");
			}
			dir = dir + "/" + type;
			File _dir = new File(dir);
			if (!_dir.exists()) {
				_dir.mkdirs();
			}
			attachWithType.put(type, dir);
			result = dir;
		}
		return result;
	}

	public static byte[][] GenerateKeyAndIV(int keyLength, int ivLength, int iterations, byte[] salt, byte[] password,
			MessageDigest md) {

		int digestLength = md.getDigestLength();
		int requiredLength = (keyLength + ivLength + digestLength - 1) / digestLength * digestLength;
		byte[] generatedData = new byte[requiredLength];
		int generatedLength = 0;

		try {
			md.reset();

			// Repeat process until sufficient data has been generated
			while (generatedLength < keyLength + ivLength) {

				// Digest data (last digest if available, password data, salt if
				// available)
				if (generatedLength > 0)
					md.update(generatedData, generatedLength - digestLength, digestLength);
				md.update(password);
				if (salt != null)
					md.update(salt, 0, 8);
				md.digest(generatedData, generatedLength, digestLength);

				// additional rounds
				for (int i = 1; i < iterations; i++) {
					md.update(generatedData, generatedLength, digestLength);
					md.digest(generatedData, generatedLength, digestLength);
				}

				generatedLength += digestLength;
			}

			// Copy key and IV into separate byte arrays
			byte[][] result = new byte[2][];
			result[0] = Arrays.copyOfRange(generatedData, 0, keyLength);
			if (ivLength > 0)
				result[1] = Arrays.copyOfRange(generatedData, keyLength, keyLength + ivLength);

			return result;

		} catch (DigestException e) {
			throw new RuntimeException(e);

		} finally {
			// Clean out temporary data
			Arrays.fill(generatedData, (byte) 0);
		}
	}
}
